import 'dart:math';

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:kq_flutter_core_widget/utils/kq_screen_util.dart';
import 'package:kq_flutter_core_widget/widgets/table/table.dart';
import 'package:kq_flutter_core_widget/widgets/table/render/kq_text_cell_render.dart';
import 'package:easy_refresh/easy_refresh.dart';
import 'package:kq_flutter_tv_widgets_example/resources/Images.dart';

/// 表格组件Demo
class TableDemoPage extends StatefulWidget {
  const TableDemoPage({super.key});

  @override
  State<StatefulWidget> createState() => _TableDemoPageState();
}

class _TableDemoPageState extends State<TableDemoPage> {
  final TableController _tableController = TableController();
  int updateTime = DateTime.now().microsecondsSinceEpoch;
  final GlobalKey _tableTopRow = GlobalKey();
  final GlobalKey _tableTopRow2 = GlobalKey();

  var tableData = [
    [
      TableData(text: "序号"),
      TableData(text: "计划单号"),
      TableData(text: "任务单号"),
      TableData(text: "产品名称"),
      TableData(text: "订单编号"),
      TableData(text: "产品编号"),
      TableData(text: "模具编号"),
      TableData(text: "模具名称"),
      TableData(text: "产品重量"),
      TableData(text: "是否可用"),
      TableData(text: "操作"),
    ],
    for (int i = 0; i < 99; i++)
      [
        TableData(text: "${i + 1}"),
        TableData(text: "P100000$i"),
        TableData(text: "T20000$i"),
        TableData(text: "产品名称$i"),
        TableData(text: "NO.2359xxxxxxxxxxx$i"),
        TableData(text: "PNO.5679$i"),
        TableData(text: "MNO.3568$i"),
        TableData(text: "模具名称$i"),
        TableData(text: "${Random().nextInt(1000)}g"),
        TableData(valid: Random().nextInt(1000) > 50),
        TableData(text: "删除", delete: true),
      ]
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          Visibility(
              visible: false,
              child: InkWell(
                key: _tableTopRow2,
                onTap: () => setState(() {
                  if (tableData.length > 50) {
                    tableData.removeRange(40, 100);
                    setState(() {});
                  } else {
                    for (int i = tableData.length - 1; i < 100; i++) {
                      tableData.add([
                        TableData(text: "${i + 1}"),
                        TableData(text: "P100000$i"),
                        TableData(text: "T20000$i"),
                        TableData(text: "产品名称$i"),
                        TableData(text: "NO.2359$i"),
                        TableData(text: "PNO.5679$i"),
                        TableData(text: "MNO.3568$i"),
                        TableData(text: "模具名称$i"),
                        TableData(text: "${Random().nextInt(1000)}g"),
                        TableData(valid: Random().nextInt(1000) > 50),
                        TableData(text: "删除", delete: true),
                      ]);
                    }
                    setState(() {});
                  }
                }),
                child: ColoredBox(
                  key: _tableTopRow,
                  color: Colors.white,
                  child: Container(
                    width: double.infinity,
                    alignment: Alignment.center,
                    child: const Padding(
                      padding:
                          EdgeInsets.symmetric(vertical: 20, horizontal: 30),
                      child: Text("改变数据"),
                    ),
                  ),
                ),
              )),
          Expanded(
            child: EasyRefresh.builder(
              header: const ClassicHeader(),
              onRefresh: () async {
                await Future.delayed(const Duration(seconds: 2));
                return Future(() => null);
              },
              childBuilder: (BuildContext context, ScrollPhysics physics) {
                return _buildTable(physics);
              },
            ),
          )
        ],
      ),
    );
  }

  Widget _buildTable(ScrollPhysics scrollPhysics) {
    return KqTable(
      columnCount: tableData[0].length,
      rowCount: tableData.length,
      updateTime: updateTime,
      fixTopCount: 1,
      fixLeftCount: 1,
      syncInitAllColumnWidth: true,
      syncInitAllRowHeight: true,
      tableController: _tableController,
      verticalScrollPhysics: scrollPhysics,
      cellBoxConstraints: (row, column) => BoxConstraints(
          minWidth: 50.r, maxWidth: 200.r, minHeight: 50.r, maxHeight: 200.r),
      couldDragChangeWidth: (row, column) => row == 0,
      couldDragChangeHeight: (row, column) => column == 0,
      cellWidthMeasure: (int row, int column) => 100.r,
      cellHeightMeasure: (int row, int column) => 50.r,
      cellRender: _buildCellRender(),
      headers: [
        SliverToBoxAdapter(
          child: ColoredBox(
            color: Colors.white,
            child: Padding(
              padding: EdgeInsets.symmetric(vertical: 20.r, horizontal: 10.r),
              child: Text(
                "表格头",
                style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20.sp),
              ),
            ),
          ),
        ),
      ],
      footers: [
        SliverToBoxAdapter(
          child: Padding(
            padding: EdgeInsets.symmetric(vertical: 50.r),
            child: const Text("表格底部内容1"),
          ),
        ),
      ],
    );
  }

  CellRender _buildCellRender() {
    var cellConfig = KqTextCellConfig(
        borderColor: Colors.grey,
        alignment: Alignment.center,
        borderWidth: 1.r,
        longPressBackground: Colors.amberAccent,
        isMultiLine: true,
        maxLines: 2,
        textOverflow: TextOverflow.ellipsis);

    return CustomCellRender(
      (row, column) => tableData[row][column],
      cellConfigBuilder: (row, column) {
        cellConfig.background =
            row == 0 || column == 0 ? Colors.grey[300] : null;
        var data = tableData[row][column];
        if (data.delete == true) {
          cellConfig.textStyle = const TextStyle(color: Colors.blue);
        } else {
          cellConfig.textStyle = const TextStyle(color: Colors.black);
        }
        return cellConfig;
      },
      highLightBuilder: _buildHighLight,
      onTapBuilder: (row, column) {
        if (tableData[row][column].delete == true) {
          return (row, column) {
            setState(() {
              tableData.removeAt(row);
            });
          };
        }

        return null;
      },
    );
  }

  HighLight? _buildHighLight(int row, int column) {
    if (row == 0 && column == 0) {
      return HighLight(Colors.blue[50]!, row: 0, column: 0);
    } else if (row == 0) {
      return HighLight(Colors.blue[50]!, column: column);
    } else if (column == 0) {
      return HighLight(Colors.blue[50]!, row: row);
    } else {
      return null;
    }
  }
}

class CustomCellRender extends KqTextCellRender<TableData> {
  CustomCellRender(super.dataBuilder,
      {super.cellConfigBuilder, super.onTapBuilder, super.highLightBuilder});

  @override
  Widget buildBody(BuildContext context, int row, int column, double width,
      double height, bool isLongPress) {
    var data = dataBuilder.call(row, column);
    if (data.valid != null) {
      Image image;
      var size = 30.r;
      if (data.valid == true) {
        image = Image.asset(Images.demoRight, width: size, height: size);
      } else {
        image = Image.asset(Images.demoError, width: size, height: size);
      }
      return Align(alignment: Alignment.center,child: image);
    }

    return super.buildBody(context, row, column, width, height, isLongPress);
  }

  @override
  String getCellText(TableData t) {
    return t.text ?? "";
  }
}

class TableData {
  String? text;
  Color? textColor;
  bool? valid;
  bool? delete;

  TableData({this.text, this.delete, this.textColor, this.valid});
}

class Test extends ClampingScrollPhysics {
  final ScrollController? parentScrollController;

  const Test({super.parent, this.parentScrollController});

  @override
  Test applyTo(ScrollPhysics? ancestor) {
    return Test(
        parent: buildParent(ancestor),
        parentScrollController: parentScrollController);
  }

  @override
  double applyPhysicsToUserOffset(ScrollMetrics position, double offset) {
    // print("applyPhysicsToUserOffset to Parent:$offset}");
    if (parent == null || shouldAcceptUserOffsetBySelf(position)) {
      return offset;
    }

    if (parent != null && parent!.shouldAcceptUserOffset(position)) {
      var bounds = parent!.applyBoundaryConditions(position, offset);
      print("bounds:$bounds,offset:$offset");
      parentScrollController
          ?.jumpTo(parentScrollController!.offset - offset + bounds);
    }

    return 0;

    // print("applyPhysicsToUserOffset to Parent:$offset}");
    // return super.applyPhysicsToUserOffset(position, offset);
  }

  @override
  double applyBoundaryConditions(ScrollMetrics position, double value) {
    if (parent == null || shouldAcceptUserOffsetBySelf(position)) {
      return super.applyBoundaryConditions(position, value);
    }

    return 0;
  }

  bool shouldAcceptUserOffsetBySelf(ScrollMetrics position) {
    ScrollDirection? scrollDirection;
    if (position is ScrollPositionWithSingleContext) {
      scrollDirection = position.userScrollDirection;
    }

    // print("position:$scrollDirection");
    if (position.minScrollExtent > position.maxScrollExtent) {
      return false;
    }

    if (scrollDirection != null &&
        position.pixels <= position.minScrollExtent &&
        scrollDirection == ScrollDirection.forward) {
      return false;
    }

    if (scrollDirection != null &&
        position.pixels >= position.maxScrollExtent &&
        scrollDirection == ScrollDirection.reverse) {
      return false;
    }

    // print("not outOfRange:$position");
    return position.pixels != 0.0 ||
        position.minScrollExtent != position.maxScrollExtent;
  }

  @override
  bool shouldAcceptUserOffset(ScrollMetrics position) {
    print("shouldAcceptUserOffset");
    if (shouldAcceptUserOffsetBySelf(position)) {
      return true;
    }

    if (parent == null) {
      return false;
    }

    return parent!.shouldAcceptUserOffset(position);
  }
}

class MyScrollController extends ScrollController {
  final MyScrollController? parent;

  MyScrollController(
      {this.parent,
      double initialScrollOffset = 0.0,
      super.keepScrollOffset = true,
      super.debugLabel});

  @override
  ScrollPosition createScrollPosition(ScrollPhysics physics,
      ScrollContext context, ScrollPosition? oldPosition) {
    return MyScrollPosition(
        physics: physics,
        context: context,
        initialPixels: initialScrollOffset,
        keepScrollOffset: keepScrollOffset,
        oldPosition: oldPosition,
        debugLabel: debugLabel,
        controller: this);
  }
}

class MyScrollPosition extends ScrollPositionWithSingleContext {
  static String tableLabel = "table";

  final MyScrollController? controller;

  MyScrollPosition(
      {required super.physics,
      required super.context,
      double? initialPixels = 0.0,
      this.controller,
      super.keepScrollOffset,
      super.oldPosition,
      super.debugLabel});

  @override
  void applyUserOffset(double delta) {
    var parentController = controller?.parent;
    if (parentController == null || !parentController.hasClients) {
      super.applyUserOffset(delta);
      return;
    }

    var parentPosition = parentController.position;
    if (parentPosition is! MyScrollPosition) {
      super.applyUserOffset(delta);
      return;
    }

    ScrollDirection direction =
        delta > 0.0 ? ScrollDirection.forward : ScrollDirection.reverse;
    if (direction == ScrollDirection.forward) {
      print("parent first");
      var oldPos = parentPosition.pixels;
      if (parentPosition.activity?.isScrolling == true) {
        parentPosition.applyUserOffset(delta);
      } else {
        parentPosition.drag(DragStartDetails(), () {});
        parentPosition.applyUserOffset(delta);
      }
      var newPos = oldPos - parentPosition.pixels;
      if (newPos != 0 && activity?.isScrolling == true) {
        super.applyUserOffset(delta);
      }
    } else {
      print("self first");
      var oldPos = pixels;
      if (activity?.isScrolling == true) {
        super.applyUserOffset(delta);
      }
      var newPos = oldPos - pixels;
      if (newPos != 0 && parentPosition.activity?.isScrolling == true) {
        parentPosition.applyUserOffset(delta);
      } else {
        parentPosition.drag(DragStartDetails(), () {});
        parentPosition.applyUserOffset(delta);
      }
    }
  }

  @override
  void goBallistic(double velocity) {
    super.goBallistic(velocity);
  }

// @override
// void updateUserScrollDirection(ScrollDirection value) {
//   super.updateUserScrollDirection(value);
// }
}
